import { Component, EventEmitter, Injector, Output, ViewChild } from '@angular/core';
import { JsonEditorComponent, JsonEditorOptions } from '@app/shared/common/json-editor/json-editor.component';
import { HttpClient} from '@angular/common/http';
import { AppConsts } from '@shared/AppConsts';
import { CustomConfigServiceProxy, PagedCustomConfigDto } from '@shared/service-proxies/service-proxies';
import { ModalDirective } from 'ngx-bootstrap/modal';
import { finalize } from 'rxjs/operators';
import { AppModalComponentBase } from '@shared/common/app-modal-component-base';

@Component({
    selector: 'custom-config-modal',
    templateUrl: './custom-config-modal.component.html'
})
export class CustomConfigModalComponent extends AppModalComponentBase {

    @ViewChild('modal', { static: true }) modal: ModalDirective;
    @ViewChild('editor', { static: false }) editor: JsonEditorComponent;
    
    @Output() callback: EventEmitter<any> = new EventEmitter<any>();

    editorOptions: JsonEditorOptions;
    
    saving = false;
    loading = false;
    jsonData: any = {};
    formEdit = false;

    title: string;

    data: PagedCustomConfigDto;

    dataTypes: string[] = ["SingleFile", "MultiFiles", "ContentDefinition", "Other"];

    private schemaCache :{[key:string]: any} = {};

    constructor(
        injector: Injector,
        private http: HttpClient,
        private _customConfigServiceProxy: CustomConfigServiceProxy
    ) {
        super(injector);
        this.data = new PagedCustomConfigDto();

        this.editorOptions = new JsonEditorOptions();
        this.editorOptions.modes = ['text','code', 'tree', 'view']; 
        this.editorOptions.mode = 'text';
        this.editorOptions.expandAll = true;
    }


    show(id: string, title : string) {
        this.data = new PagedCustomConfigDto();
        this.title = title;
        this.data.dataType = "Other";

        this.formEdit = false;

        if (id) {
            this.init(id);
        }else{
            this.jsonData = {};
            this.editor.data = this.jsonData;
            
            this.getSchema(this.data.dataType, (schema)=>{
                this.editorOptions.schema = schema;
                this.editor.setSchema(schema,{});
            });

        }
        
        this.modal.show();
    }

    close(): void {
        this.modal.hide();
    }


    init(id: string) {
        this.loading = true;
        this._customConfigServiceProxy.get(id)
            .pipe(finalize(() => this.loading = false))
            .subscribe(result => {
                this.data = result;
                this.title = result.name;
                if (this.data.extensionData) {
                    this.jsonData = JSON.parse(this.data.extensionData);
                } else {
                    this.jsonData = {};
                }
                this.editor.data = this.jsonData;

                this.getSchema(this.data.dataType, (schema)=>{
                    this.editorOptions.schema = schema;
                    this.editor.setSchema(schema,{});
                });
            });
    }

    save() {
        if (!this.saving && !this.loading) {
            this.saving = true;
            this.data.extensionData = JSON.stringify(this.jsonData, null, 4);

            if (this.data.id) {
                this._customConfigServiceProxy.update(this.data)
                    .pipe(finalize(() => this.saving = false))
                    .subscribe(result => {
                        this.notify.success(this.l('SavedSuccessfully'));
                        this.callback.emit();
                        this.close();
                    });
            } else {
                this._customConfigServiceProxy.create(this.data)
                    .pipe(finalize(() => this.saving = false))
                    .subscribe(result => {
                        this.notify.success(this.l('SavedSuccessfully'));
                        this.callback.emit();
                        this.close();
                    });
            }
        }
    }

    dataTypeChanged(){
        if(!this.data.dataType){
            return;
        }

        this.getSchema(this.data.dataType, (schema)=>{
            this.editorOptions.schema = schema;
            this.editor.setSchema(schema,{});
        });
    }

    private getSchema(dataType: string, func: {(schema):void}): void {
        if (dataType === 'Other') {
            func({});
            return;
        }

        let schema =this.schemaCache[dataType];
        if(schema){
            func(schema);
            return;
        }

        this.http.get(AppConsts.appBaseUrl + `/assets/config/${dataType}.json`)
            .subscribe(r=>{
                this.schemaCache[dataType] = r; 
               func(r);
        });

        // TODO: 定制json 校验规则 http://json-schema.org/understanding-json-schema/,
        // https://github.com/json-editor/json-editor
        // https://github.com/josdejong/jsoneditor  目前使用的这一个
    }
}
